#ifndef _network_Types_hpp_
#define _network_Types_hpp_

/** \file Types.hpp Types for network stuff
 *  \author Adrian Schweizer
 *  \created  $So 19 Aug 02:31:06 pm CEST 2007 schwadri@SchwadriComp.local$
 *  \modified $Sa 19 Jan 10:42:34 pm CET 2008 schwadri@SchwadriLaptop.local$
 */

#include "../core/types.hpp"
#include "Address.hpp"
#include <limits>
#include <bitset>

namespace network {

    //forward decls
    //class Client;
    //class NetworkController;

    /** \todo this must be the corrected to a value after all raknet msg id's
     *  so that the action dispatcher does not use id's that are already in use
     */
    static const int            ID_GAME_ACTION_BEGIN = 100;

    #define NETWORK_RECEIVER_MASK_SIZE   64
    /** \brief receiver bit mask
     *
     *  a bit mask where each bit defines whether a specific client should
     *  receive an action or not. If a bit is set the network module of the
     *  host/server will forward the action to the specific client (if it exists).
     *  bits corresponding to non existing clients are ignored.
     */
    class receiver_mask    :   public std::bitset<NETWORK_RECEIVER_MASK_SIZE>
    {
        typedef std::bitset<NETWORK_RECEIVER_MASK_SIZE> base_type;
    
    public:
        /** \brief Ctor with all receivers enabled
         */
        receiver_mask()
        {
            set();
        }
        
        /** \brief Ctor with one single receiver set
         *
         *  \param[in] cid 
         */
        explicit receiver_mask(std::size_t cid)
        {
            set(cid);
        }

        receiver_mask& operator+=(std::size_t cid)
        {
            set(cid);
            return *this;
        }

        receiver_mask& operator-=(std::size_t cid)
        {
            reset(cid);
            return *this;
        }

        bool    operator&(std::size_t cid)
        {
            return test(cid);
        }
    };


    //static const receiver_mask RECEIVER_ALL    = std::numeric_limits<receiver_mask>::max();   ///< receiver bit mask specifying that all clients should receive the action
    //static const receiver_mask RECEIVER_NONE   = 0x0;                                         ///< receiver bit mask specifying that no receiver should get the action
    static const unsigned int RECEIVER_SERVER = 0x1;                                         ///< receiver bit mask specifying that the server should get the action

    enum DisconnectReason {
        UNKNOWN,
        SERVER_FULL,
        CONNECTION_FAILED,
        KICKED,
        BANNED,
        TIMED_OUT,
        VERSION_MISMATCH,
        CLOSED,
        WRONG_PASSWORD
    };

    /** \brief Reliablitiy levels to send messages with
     * These enumerations are used to describe how packets are delivered.
     * Note: Copied from RakNet's packetpriority.h
     */
    enum ReliabilityLevel
    {
	    UNRELIABLE,   // Same as regular UDP, except that it will also discard duplicate datagrams.  RakNet adds (6 to 17) + 21 bits of overhead, 16 of which is used to detect duplicate packets and 6 to 17 of which is used for message length.
	    UNRELIABLE_SEQUENCED,  // Regular UDP with a sequence counter.  Out of order messages will be discarded.  This adds an additional 13 bits on top what is used for UNRELIABLE.
	    RELIABLE,   // The message is sent reliably, but not necessarily in any order.  Same overhead as UNRELIABLE.
	    RELIABLE_ORDERED,   // This message is reliable and will arrive in the order you sent it.  Messages will be delayed while waiting for out of order messages.  Same overhead as UNRELIABLE_SEQUENCED.
	    RELIABLE_SEQUENCED // This message is reliable and will arrive in the sequence you sent it.  Out or order messages will be dropped.  Same overhead as UNRELIABLE_SEQUENCED.
    };
    //@}

} // namespace network

#endif // _network_Types_hpp_
